define([
    'app',
    'metisMenu',
    'zTree-exhide'
], function(app) {
    app.controller('workbench', function($rootScope, $scope, $http, $cookies, $location, $timeout, $filter, cfpLoadingBar,
            $routeParams, $q, Upload, toastr, hotkeys, _dialog) {
        var self = this;

        // =================================================== navbar =============================================== //

        self.navbar = {
            'file': {
                'new': {
                    enabled: true,
                    module: { enabled: true, click: function() {
                        _dialog.open().editModule({ module: '' }).then(function(module) {
                            var newNode = zTreeObj.addNodes(null, {
                                name: module, module: true, iconSkin: 'module', children: []
                            })[0];
                            zTreeObj.selectNode(newNode);
                        });
                    }},
                    file: { enabled: true, click: function() {
                        _dialog.open().editFile({ file: '' }).then(function(file) {
                            if (file) {
                                self.editor.open({ name: file });
                            }
                        });
                    }}
                },
                'open': { enabled: true, click: function(file) {
                    if (file != null) {
                        Upload.upload({
                            url: '/note/file/read',
                            method: 'POST',
                            data: {
                                'Content-Type': (file.type ? file.type : 'application/octet-stream'),
                                'filename': file.name,
                                'file': file
                            },
                            transformResponse: function(response) {
                                return response;
                            }
                        }).then(function(response) {
                            if (response.status == 200) {
                                self.editor.open({ name: file.name, data: response.data });
                            }
                        });
                    }
                }},
                'save': { enabled: false, click: null },
                'saveAs': { enabled: false, click: function() {
                    self.editor.saveAs();
                }},
                'save': { enabled: false, click: null },
                'refresh': { enabled: true, click: function() {
                    loadTreeNodes();
                }},
                'search': { click: function() {
                    _dialog.open().searchFile().then(function(file) {
                        if (file) {
                            self.editor.open({ name: file.name, path: file.path });
                        }
                    });
                }},
                'history': { enabled: true, click: function() {
                    _dialog.open().showFilesHistory({ path: '' });
                }},
                'close': { enabled: false, click: function() {
                    self.editor.close();
                }},
                'closeAll': { enabled: false, click: function() {
                    self.editor.closeAll();
                }}
            },
            'edit': {
                'undo': { enabled: false, click: null },
                'redo': { enabled: false, click: null },
                'cut': { enabled: false, click: null },
                'copy': { enabled: false, click: null },
                'paste': { enabled: false, click: null },
                'selectAll': { enabled: false, click: null },
                'delete': { enabled: false, click: null },
                'find': { enabled: false, click: null },
                'format': { enabled: false, click: null }
            },
            'view': {
                'autowrap': { checked: true, click: function() {
                    this.checked = !this.checked;
                    $scope.$broadcast('@editor.option', { wrap: this.checked });
                }},
                'show': {
                    lineno: { checked: true, click: function() {
                        this.checked = !this.checked;
                        $scope.$broadcast('@editor.option', { showLineNumbers: this.checked });
                    }},
                    printline: { checked: false, click: function() {
                        this.checked = !this.checked;
                        $scope.$broadcast('@editor.option', { showPrintMargin: this.checked });
                    }},
                    whitespace: { checked: false, click: function() {
                        this.checked = !this.checked;
                        $scope.$broadcast('@editor.option', { showInvisibles: this.checked });
                    }}
                },
                'sidebar': { checked: true, click: function() {
                    this.checked = !this.checked;
                    $scope.$broadcast('@resize.all');
                }},
                'toolbar': { checked: true, click: function() {
                    this.checked = !this.checked;
                    $scope.$broadcast('@resize.all');
                }},
                'statusbar': { checked: true, click: function() {
                    this.checked = !this.checked;
                    $scope.$broadcast('@resize.all');
                }},
                'fullscreen': { enabled: false, checked: false, click: function() {
                    this.checked = !this.checked;
                    var fullscreen = (this.checked ? 'true' : null);
                    $location.path($location.path(), false).search('fullscreen', fullscreen).replace();
                    // rerender actived tab
                    $timeout(function() {
                        if (self.editor.active) {
                            renderActivedTab(self.editor.active);
                        }
                    });
                    $scope.$broadcast('@resize.all');
                }}
            },
            'tool': {
                'theme': { selected: 'Chrome', themes: [
                    'Chrome', 'Eclipse', 'GitHub', 'XCode', 'Terminal'
                ], click: function(theme) {
                    if (this.selected != theme) {
                        this.selected = theme;
                        $scope.$broadcast('@editor.option', {
                            theme: 'ace/theme/' + this.selected.toLowerCase()
                        });
                    }
                }},
                'font': { selected: 14,
                    fonts: [8, 9, 10, 11, 12, 14, 16, 20],
                    click: function(font) {
                        if (this.selected != font) {
                            this.selected = font;
                            $scope.$broadcast('@editor.option', { fontSize: this.selected });
                        }
                    }
                }
            },
            'help': {
                'shortcut': { click: function() {
                    _dialog.open().showShortcutKey();
                }},
                'user': {
                    login: { click: function() {
                        _dialog.open().security();
                    }},
                    password: { click: function() {
                        _dialog.open().editPassword();
                    }},
                    logout: { click: function() {
                        $http.post('/note/auth/logout').then(function(response) {
                            if (response.status == 200) {
                                $rootScope.sessionUser = {};
                                $cookies.remove('session_user');
                                toastr.success('用户退出成功！');
                                // check access
                                $rootScope.accessible = response.data['accessible'];
                                if (!response.data['accessible']) {
                                    _dialog.open().security();
                                }
                            }
                        });
                    }}
                }
            }
        };

        // ================================================== toolbar =============================================== //

        self.toolbar = {
            'undo': self.navbar['edit']['undo'],
            'redo': self.navbar['edit']['redo'],
            'cut': self.navbar['edit']['cut'],
            'copy': self.navbar['edit']['copy'],
            'paste': self.navbar['edit']['paste'],
            'save': self.navbar['file']['save']
        }

        // ================================================== sidebar =============================================== //

        self.sidebar = {
            'new': {
                enabled: false,
                folder: { click: null },
                file: { click: null }
            },
            'open': { enabled: false, click: null },
            'rename': { click: null },
            'copy': { enabled: false, click: null },
            'delete': { click: null },
            'save': { enabled: false, click: null },
            'saveAs': { enabled: false, click: null },
            'refresh': { click: null },
            'history': { click: null }
        };

        var zTreeObj = null;
        var zTreeSetting = {
            view: {
                showTitle: true
            },
            callback: {
                onRemove: function(event, treeId, treeNode) {
                    var parentNode = treeNode.getParentNode();
                    if (parentNode && parentNode.isParent == false) {
                        if (parentNode.module || parentNode.folder) {
                            //parentNode.open = true;
                            parentNode.isParent = true;
                            zTreeObj.updateNode(parentNode);
                        }
                    }
                },
                onDblClick: function(event, treeId, treeNode) {
                    if (treeNode && treeNode.file) {
                        $timeout(function() {
                            self.editor.open({
                                name: treeNode.name,
                                path: getNodePath(treeNode)
                            });
                        });
                    }
                },
                onRightClick: function(event, treeId, treeNode) {
                    if (treeNode) {
                        zTreeObj.selectNode(treeNode);
                        var nodePath = getNodePath(treeNode);
                        if (treeNode.file) {
                            self.sidebar['new'].enabled = false;
                            self.sidebar['open'].enabled = true;
                            self.sidebar['open'].click = function() {
                                self.editor.open({ name: treeNode.name, path: nodePath });
                            };
                            var oneFile = _.find(self.editor.files, function(file) {
                                return file.path == nodePath && file.changed;
                            });
                            self.sidebar['save'].enabled = oneFile ? true : false;
                            self.sidebar['save'].click = function() {
                                self.editor.save(oneFile);
                            };
                            self.sidebar['saveAs'].enabled = true;
                            self.sidebar['saveAs'].click = function() {
                                self.editor.saveAs({ name: treeNode.name, path: nodePath });
                            };
                        } else {
                            self.sidebar['new'].enabled = true;
                            self.sidebar['new']['folder'].click = function() {
                                _dialog.open().editFolder({ folder: '', parent: nodePath }).then(function(folder) {
                                    var newNode = zTreeObj.addNodes(treeNode, {
                                        name: folder, folder: true, children: []
                                    })[0];
                                    zTreeObj.selectNode(newNode);
                                });
                            };
                            self.sidebar['new']['file'].click = function() {
                                _dialog.open().editFile({ file: '', parent: nodePath }).then(function(file) {
                                    var newNode = zTreeObj.addNodes(treeNode, { name: file, file: true })[0];
                                    zTreeObj.selectNode(newNode);
                                    $('#' + newNode.tId + '>a').trigger('dblclick');
                                });
                            };
                            self.sidebar['open'].enabled = false;
                            self.sidebar['save'].enabled = false;
                            self.sidebar['saveAs'].enabled = false;
                        }

                        self.sidebar['rename'].click = function() {
                            if (treeNode.module) {
                                _dialog.open().editModule({ module: treeNode.name }).then(function(module) {
                                    var pathRegex = new RegExp('^' + nodePath + '/');
                                    _.each(self.editor.files, function(file) {
                                        // 同步打开文件的路径
                                        if (pathRegex.test(file.path)) {
                                            var filePath = file.path;
                                            file.path = file.path.replace(pathRegex, module + '/');
                                            if (file.opened && ('/' + filePath) == $location.path()) {
                                                $location.path('/' + file.path, false).replace();
                                            }
                                        }
                                    });
                                    treeNode.name = module;
                                    zTreeObj.updateNode(treeNode);
                                });
                            } else {
                                var nodeName = treeNode.name;
                                var parentPath = getNodePath(treeNode.getParentNode());
                                if (treeNode.folder) {
                                    _dialog.open().editFolder({ folder: nodeName, parent: parentPath }).then(function(folder) {
                                        var pathRegex = new RegExp('^' + nodePath + '/');
                                        _.each(self.editor.files, function(file) {
                                            // 同步打开文件的路径
                                            if (pathRegex.test(file.path)) {
                                                var filePath = file.path;
                                                file.path = file.path.replace(pathRegex, parentPath + '/' + folder + '/');
                                                if (file.opened && ('/' + filePath) == $location.path()) {
                                                    $location.path('/' + file.path, false).replace();
                                                }
                                            }
                                        });
                                        treeNode.name = folder;
                                        zTreeObj.updateNode(treeNode);
                                    });
                                } else {
                                    _dialog.open().editFile({ file: nodeName, parent: parentPath }).then(function(file) {
                                        var oneFile = _.find(self.editor.files, function(_file) {
                                            return _file.path == nodePath;
                                        });
                                        if (oneFile) {
                                            oneFile.name = file;
                                            oneFile.path = parentPath + '/' + file;
                                            // 同步打开文件的路径与名称
                                            if (oneFile.opened && ('/' + nodePath) == $location.path()) {
                                                $location.path('/' + oneFile.path, false).replace();
                                            }
                                            // 更新文件列表标签
                                            $timeout(function() {
                                                if (oneFile.id == self.editor.active) {
                                                    renderActivedTab(self.editor.active);
                                                }
                                            });
                                        }
                                        treeNode.name = file;
                                        zTreeObj.updateNode(treeNode);
                                    });
                                }
                            }
                        };
                        self.sidebar['copy'].enabled = !treeNode.module;
                        self.sidebar['copy'].click = function() {
                            if (treeNode.folder) {
                                _dialog.open().copyFolder({ path: nodePath });
                            } else if (treeNode.file) {
                                _dialog.open().copyFile({ path: nodePath });
                            }
                        };
                        self.sidebar['delete'].click = function() {
                            _dialog.confirm('确认信息', '您确定要删除【' + treeNode.name + '】吗？').then(function(yes) {
                                if (yes) {
                                    if (treeNode.module) {
                                        var module = treeNode.name;
                                        $http.delete('/note/module/delete?module=' + module).then(function(response) {
                                            if (response.data == 'required') {
                                                _dialog.alert('提示信息', '模块【' + module + '】不存在！');
                                            } else if (response.data) {
                                                closeDeletedFiles(nodePath);
                                                setTimeout(function() {
                                                    zTreeObj.removeNode(treeNode);
                                                    zTreeSetting.callback.onRemove(event, treeId, treeNode);
                                                    toastr.success('模块【' + module + '】已删除！');
                                                }, 500);
                                            }
                                        });
                                    } else {
                                        var module = nodePath.substring(0, nodePath.indexOf('/'));
                                        $http.delete('/note/data/delete', {
                                            params: { module: module, path: nodePath.substring(module.length + 1) }
                                        }).then(function(response) {
                                            if (response.data == 'required') {
                                                _dialog.alert('提示信息', '模块【' + module + '】不存在！');
                                            } else if (response.data) {
                                                closeDeletedFiles(nodePath, treeNode.file);
                                                setTimeout(function() {
                                                    zTreeObj.removeNode(treeNode);
                                                    zTreeSetting.callback.onRemove(event, treeId, treeNode);
                                                    if (treeNode.file) {
                                                        toastr.success('文件【' + treeNode.name + '】已删除！');
                                                    } else {
                                                        toastr.success('文件夹【' + treeNode.name + '】已删除！');
                                                    }
                                                }, 500);
                                            }
                                        });
                                    }
                                }
                            });
                        };
                        self.sidebar['refresh'].enabled = !treeNode.file;
                        self.sidebar['refresh'].click = function() {
                            $http.get('/note/data/tree?basedir=' + nodePath).then(function(response) {
                                if (response.status == 200) {
                                    if (response.data == '404') {
                                        zTreeObj.removeNode(treeNode);
                                        _dialog.alert('提示信息', '文件夹【' + treeNode.name + '】不存在！');
                                    } else {
                                        zTreeObj.removeChildNodes(treeNode);
                                        zTreeObj.addNodes(treeNode, response.data.children);
                                    }
                                }
                            });
                        };
                        self.sidebar['history'].click = function() {
                            if (treeNode.file) {
                                _dialog.open().showFileHistory({
                                    file: treeNode.name,
                                    path: nodePath
                                }).then(function(refreshable) {
                                    if (refreshable) {
                                        var oneFile = _.find(self.editor.files, function(file) {
                                            return file.path == nodePath;
                                        });
                                        if (typeof(oneFile.reloader) === 'function') {
                                            oneFile.reloader(self.editor);
                                        }
                                    }
                                });
                            } else {
                                _dialog.open().showFilesHistory({ path: nodePath });
                            }
                        };

                        $timeout(function() {
                            $scope.$apply();
                        });
                    }
                }
            }
        };

        // =================================================== editor =============================================== //

        self.editor = {
            active: '',
            files: [],
            idOffset: 0,
            open: function(file) {
                if (file) {
                    var _this = self.editor;
                    var index = -1;
                    if (file.id) {
                        // opened file
                        var oneFile = _.find(_this.files, function(_file) {
                            return _file.id == file.id;
                        });
                        index = _this.files.indexOf(oneFile);
                    } else if (file.path) {
                        // new file or not saved file
                        var oneFile = _.find(_this.files, function(_file) {
                            return _file.path == file.path;
                        });
                        if (oneFile) {
                            index = _this.files.indexOf(oneFile);
                        }
                    }
                    if (index < 0) {
                        index = _this.files.length;
                        _this.files.push({
                            id: 'file-id-' + (_this.idOffset++),
                            name: file.name,
                            path: file.path,
                            extension: file.name.substring(file.name.lastIndexOf('.')),
                            data: file.data || '',
                            opened: false,
                            changed: false,
                            renderer: null,
                            reloader: null,
                            extractor: null
                        });
                    }
                    $timeout(function() {
                        _this.active = _this.files[index].id;
                        self.navbar['file']['saveAs'].enabled = true;
                        self.navbar['file']['close'].enabled = true;
                        self.navbar['file']['closeAll'].enabled = true;
                        self.navbar['view']['fullscreen'].enabled = true;
                    });
                }
            },
            read: function(file) {
                var defer = $q.defer();
                $http.get('/note/data/read?file=' + file.path).then(function(response) {
                    if (response.status == 200) {
                        if (response.data == '404') {
                            _dialog.alert('提示信息', '文件【' + file.name + '】不存在！');
                        } else {
                            file.modified = response.data.modified;
                            file.data = response.data.data;
                            defer.resolve(response.data);
                        }
                    }
                });
                return defer.promise;
            },
            save: function(file, callback, confirmed) {
                if (confirmed) {
                    saveFileDir();
                } else {
                    _dialog.confirm('确认信息', '您确定要保存文件吗？').then(function(yes) {
                        if (yes) {
                            saveFileDir();
                        }
                    });
                }

                function saveFileDir() {
                    if (file.path) {
                        saveFile();
                    } else {
                        _dialog.open().selectFolder().then(function(dir) {
                            file.path = dir + '/' + file.name;
                            saveFile();
                            $location.path('/' + file.path, false).replace();
                        });
                    }
                }

                function saveFile() {
                    var attr = parseFilePath(file.path);
                    if (typeof(file.extractor) === 'function') {
                        file.extractor();
                    }
                    $http.post('/note/data/save', {
                        module: attr.module,
                        type: 'file',
                        path: attr.path,
                        data: file.data,
                        modified: file.modified
                    }).then(function(response) {
                        setTimeout(function() {
                            if (response.data == 'required') {
                                _dialog.alert('提示信息', '模块【' + attr.module + '】不存在！');
                            } else if (response.data == 'expired') {
                                _dialog.alert('提示信息', '文件已被更新，请刷新后再保存！');
                            } else if (response.data) {
                                if (typeof(callback) === 'function') {
                                    callback();
                                }
                                // reload committed data
                                $http.get('/note/data/read?file=' + file.path).then(function(_response) {
                                    if (_response.status == 200) {
                                        var result = _response.data;
                                        file.modified = result.modified;
                                        if (file.data != result.data) {
                                            file.data = result.data;
                                            if (typeof(file.reloader) === 'function') {
                                                file.reloader(self.editor, true);
                                            }
                                        }
                                    }
                                });
                                file.changed = false;
                                self.navbar['file']['save'].enabled = false;
                                toastr.success('文件【' + file.name +'】已保存！');
                            }
                        }, 500)
                    });
                }
            },
            saveAs: function(file) {
                var _this = this;
                if (!file) {
                    file = _.find(_this.files, function(_file) {
                        return _file.id == _this.active;
                    });
                }
                if (file) {
                    if (typeof(file.extractor) === 'function') {
                        file.extractor();
                    }
                    if (!file.data && file.path) {
                        $http.get('/note/data/read?file=' + file.path).then(function(response) {
                            if (response.status == 200) {
                                if (response.data == '404') {
                                    _dialog.alert('提示信息', '文件【' + file.name + '】不存在！');
                                } else {
                                    saveAsFile(file.name, response.data.data);
                                }
                            }
                        });
                    } else {
                        saveAsFile(file.name, file.data);
                    }
                }
            },
            close: function(file) {
                var _this = this;
                if (!file) {
                    file = _.find(_this.files, function(_file) {
                        return _file.id == _this.active;
                    });
                }
                var index = _this.files.indexOf(file);
                if (index >= 0) {
                    confirmCloseFile(_this.files[index], function() {
                        _this.files.splice(index, 1);
                        if (_this.files.length == 0) {
                            _this.closeAll();
                        } else {
                            $timeout(function() {
                                if (self.editor.active) {
                                    renderActivedTab(self.editor.active);
                                }
                            });
                        }
                    });
                }
            },
            closeOthers: function(file) {
                var _this = this;
                if (_this.files.length > 1) {
                    for (var i = 0; i < _this.files.length; i++) {
                        if (_this.files[i] != file) {
                            confirmCloseFile(_this.files[i], function() {
                                _this.files.splice(i--, 1);
                                $timeout(function() {
                                    if (self.editor.active) {
                                        renderActivedTab(self.editor.active);
                                    }
                                    _this.closeOthers(file);
                                });
                            });
                            break;
                        }
                    }
                }
            },
            closeAll: function() {
                var _this = this;
                if (_this.files.length > 0) {
                    confirmCloseFile(_this.files[0], function() {
                        _this.files.splice(0, 1);
                        $timeout(function() {
                            if (self.editor.active) {
                                renderActivedTab(self.editor.active);
                            }
                            _this.closeAll();
                        });
                    });
                } else {
                    _this.files.length = 0;
                    self.navbar['file']['save'].enabled = false;
                    self.navbar['file']['saveAs'].enabled = false;
                    self.navbar['file']['close'].enabled = false;
                    self.navbar['file']['closeAll'].enabled = false;
                    self.navbar['edit']['undo'].enabled = false;
                    self.navbar['edit']['redo'].enabled = false;
                    self.navbar['edit']['cut'].enabled = false;
                    self.navbar['edit']['copy'].enabled = false;
                    self.navbar['edit']['paste'].enabled = false;
                    self.navbar['edit']['selectAll'].enabled = false;
                    self.navbar['edit']['delete'].enabled = false;
                    self.navbar['edit']['find'].enabled = false;
                    self.navbar['edit']['format'].enabled = false;
                    self.navbar['view']['fullscreen'].enabled = false;
                    self.navbar['view']['fullscreen'].checked = false;
                    self.statusbar.link = '';
                    self.statusbar.statuses = [];
                    $('.extendbar').children().css('display', 'none');
                    $location.path('/', false).replace();
                }
            }
        };

        // ================================================ statusbar =============================================== //

        self.statusbar = {
            link: '',
            statuses: []
        };

        self.context = {
            navbar: self.navbar,
            toolbar: self.toolbar,
            sidebar: self.sidebar,
            statusbar: self.statusbar
        };

        // ================================================ functions =============================================== //

        self.init = function() {
            // sidebar
            $('#side-menu').metisMenu({
                toggle: true
            }).show();
            $('#side-menu .dropdown-menu, body').click(function(event) {
                var target = (event.target || event.srcElement);
                var items = $('#side-menu>li').toArray();
                if (!_.find(items, function(item) {
                    return item == target || $('>a', item).is(target) || $('>a>i', item).is(target);
                })) {
                    $('#side-menu>li').removeClass('mm-active');
                }
            });

            // navbar
            var editorOpts = $cookies.getObject('editor.options');
            if (editorOpts) {
                if (angular.isDefined(editorOpts.wrap)) {
                    self.navbar['view']['autowrap'].checked = editorOpts.wrap;
                }
                if (angular.isDefined(editorOpts.showLineNumbers)) {
                    self.navbar['view']['show'].lineno.checked = editorOpts.showLineNumbers;
                }
                if (angular.isDefined(editorOpts.showPrintMargin)) {
                    self.navbar['view']['show'].printline.checked = editorOpts.showPrintMargin;
                }
                if (angular.isDefined(editorOpts.showInvisibles)) {
                    self.navbar['view']['show'].whitespace.checked = editorOpts.showInvisibles;
                }
                if (angular.isDefined(editorOpts.theme)) {
                    var theme = _.find(self.navbar['tool']['theme'].themes, function(_theme) {
                        return editorOpts.theme.indexOf(_theme.toLowerCase()) != -1;
                    });
                    if (theme) {
                        self.navbar['tool']['theme'].selected = theme;
                    }
                }
                if (angular.isDefined(editorOpts.fontSize)) {
                    self.navbar['tool']['font'].selected = editorOpts.fontSize;
                }
            }
            $scope.$on('@editor.option', function(event, option) {
                if (option) {
                    var options = $cookies.getObject('editor.options') || {};
                    _.each(option, function(attrValue, attrName) {
                        options[attrName] = attrValue;
                    });
                    $cookies.putObject('editor.options', options);
                }
            });
            //
            var workbenchOpts = $cookies.getObject('workbench.options');
            if (workbenchOpts) {
                if (angular.isDefined(workbenchOpts.separatorWidth)) {
                    moveSeparatorTo(workbenchOpts.separatorWidth, true);
                }
            }

            // list files
            var listFiles = [];
            listTreeNodes(listFiles, function() {
                $scope.$watch('vm.filter', function(newVal) {
                    $timeout(function() {
                        self.listFiles = $filter('keyword')(listFiles, newVal, 'name', 15);
                    });
                });
            });
            $('#filter-toggle').on('click', function() {
                $('.input-group-btn', this).addClass('open');
            });
            $(document).click(function(event) {
                var target = (event.target || event.srcElement);
                if ($('#filter-toggle').has(target).length == 0) {
                    $('#filter-toggle>.input-group-btn').removeClass('open');
                }
            });

            // zTree
            loadTreeNodes($routeParams.path);

            if ($routeParams.fullscreen == 'true') {
                if ($routeParams.path) {
                    self.navbar['view']['fullscreen'].enabled = true;
                    self.navbar['view']['fullscreen'].checked = true;
                }
            }

            $timeout(function() {
                // resize
                $(window).resize(function() {
                    $scope.$broadcast('@resize.all');
                });
                $scope.$on('@resize.all', function() {
                    $timeout(function() {
                        if (self.editor.active) {
                            renderActivedTab(self.editor.active);
                        }
                    });
                });

                // navbar dropdown menu
                $('.navbar-nav>li').click(function() {
                    $('nav[contextmenu]').removeClass('open');
                });
                // dropdown submenu
                $('.dropdown-submenu').click(function(event) {
                    var target = (event.target || event.srcElement);
                    if (target == $(this).children()[0]) {
                        return false;
                    }
                });

                // separator
                $('.separator').draggable({
                    axis: 'x',
                    delay: 200,
                    containment: 'parent',
                    drag: function(event, ui) {
                        moveSeparatorTo(ui.position.left);
                    }
                });

                // editor tabs sortable
                $('.composite>div>.nav-tabs').sortable({
                    items: '>li:not(.file-list)',
                    cancel: '.closeable',
                    containment: 'parent',
                    axis: 'x',
                    cursor: 'move',
                    placeholder: 'highlight',
                    forcePlaceholderSize: true,
                    opacity: 0.7,
                    delay: 200,
                    distance: 5,
                    //tolerance: 'pointer',
                    revert: true
                }).bind('sortupdate', function(event, ui) {
                    var ids = ui.item.parent().sortable('toArray');
                    var files = [];
                    _.each(ids, function(id) {
                        files.push(_.find(self.editor.files, function(_file) {
                            return _file.id == id;
                        }));
                    });
                    $timeout(function() {
                        self.editor.files = files;
                        renderActivedTab(ui.item.attr('id'));
                    });
                });
            });

            $scope.$watch('vm.editor.active', function(active) {
                if (active) {
                    var oneFile = _.find(self.editor.files, function(file) {
                        return file.id == active;
                    });
                    if (oneFile) {
                        function callRenderer() {
                            if (typeof(oneFile.renderer) === 'function') {
                                oneFile.renderer.call(self.context, self.editor);
                            } else {
                                $timeout(callRenderer, 10);
                            }
                        }
                        $timeout(function() {
                            $('.extendbar').children().css('display', 'none');
                            callRenderer();
                            renderActivedTab(oneFile.id);
                            //
                            if (oneFile.path) {
                                $location.path('/' + oneFile.path, false).replace();
                            } else {
                                $location.path('/', false).replace();
                            }
                        });
                    }
                }
            });

            hotkeys.add({
                combo: 'ctrl+h',
                callback: function(event) {
                    event.preventDefault();
                    self.navbar.file.search.click();
                }
            });
        }

        self.toggleFullscreen = function() {
            $timeout(function() {
                self.navbar.view.fullscreen.click();
            });
        }

        function listTreeNodes(files, callback) {
            $http.get('/note/data/tree').then(function(response) {
                if (response.status == 200) {
                    _listNodes('', response.data);
                    if (typeof(callback) === 'function') {
                        callback();
                    }
                    // list file nodes
                    function _listNodes(parent, nodes) {
                        _.each(nodes, function(node) {
                            if (node.file) {
                                files.push({ name: node.name, path: parent + node.name });
                            } else if (node.children) {
                                _listNodes(parent + node.name + '/', node.children);
                            }
                        });
                    }
                }
            });
        }

        function loadTreeNodes(path) {
            $.fn.zTree.destroy('note-tree');
            $http.get('/note/data/tree').then(function(response) {
                if (response.status == 200) {
                    var treeNodes = response.data || [];
                    _.each(treeNodes, function(node) {
                        if (node.module) {
                            node.iconSkin = 'module';
                        }
                    });
                    zTreeObj = $.fn.zTree.init($('#note-tree'), zTreeSetting, treeNodes);
                    // load current file
                    if (path) {
                        var nodes = zTreeObj.getNodesByFilter(function(node) {
                            return getNodePath(node) == path;
                        });
                        if (_.isEmpty(nodes)) {
                            if (self.navbar.view.fullscreen.checked) {
                                self.navbar.view.fullscreen.checked = false;
                            }
                            _dialog.alert('提示信息', '文件【' + path + '】不存在！');
                        } else {
                            zTreeObj.selectNode(nodes[0]);
                            zTreeObj.expandNode(nodes[0], true, false, false);
                            $('#' + nodes[0].tId + '>a').trigger('dblclick');
                        }
                    }
                }
            });
        }

        function moveSeparatorTo(width, reset) {
            $('.sidebar').css('width', (width + 200) + 'px');
            $('.composite').css('left', (width + 203) + 'px');
            if (reset) {
                $('.separator').css('left', width + 'px');
            }
            $timeout(function() {
                $scope.$broadcast('@resize.all');
                // save separator width
                var options = $cookies.getObject('workbench.options') || {};
                options['separatorWidth'] = width;
                $cookies.putObject('workbench.options', options);
            });
        }

        function renderActivedTab(id) {
            var jqFile = $('#' + id);
            if (jqFile.length > 0) {
                var jqContainer = $('.composite>div>.nav-tabs');
                var oldMarginLeft = parseFloat(jqContainer.css('margin-left'));
                var marginLeft = oldMarginLeft;
                if (jqFile.position().left < 0) {
                    //jqContainer.stop().animate({ marginLeft: '-=' + jqFile.position().left }, 200);
                    marginLeft -= jqFile.position().left;
                } else if (jqFile.position().left > 0) {
                    var viewFileX = jqFile.position().left + jqFile.width();
                    var viewWidth = $('.composite').width() - $('.file-list').width();
                    var diffMarginLeft = viewFileX - viewWidth;
                    if (diffMarginLeft > 0) {
                        //jqContainer.stop().animate({ marginLeft: '-=' + diffMarginLeft }, 200);
                        marginLeft -= diffMarginLeft;
                    } else if (diffMarginLeft < 0) {
                        if (oldMarginLeft < 0) {
                            diffMarginLeft = oldMarginLeft + viewWidth - viewFileX;
                            if (diffMarginLeft > 0) {
                                diffMarginLeft = 0;
                            }
                            //jqContainer.stop().animate({ marginLeft: diffMarginLeft }, 200);
                            marginLeft = diffMarginLeft;
                        }
                    }
                }
                if (marginLeft != oldMarginLeft) {
                    jqContainer.css('margin-left', marginLeft + 'px');
                }
            }
        }

        function saveAsFile(filename, content) {
            var jqTargetId = 'jqFormIO-' + (new Date().getTime());
            var jqForm = $('<form style="display:none" method="POST">').attr({
                    action: '/note/file/write',
                    target: jqTargetId
                }).appendTo(document.body);
            var jqIframe = $('<iframe style="display:none">').attr({
                    name: jqTargetId
                }).appendTo(document.body);

            // form data
            jqForm.append($('<input name="filename">').val(filename));
            jqForm.append($('<textarea name="content">').val(content));

            // submit
            cfpLoadingBar.start();
            jqForm.submit();

            // remove
            setTimeout(function() {
                jqForm.remove();
                jqIframe.remove();
                cfpLoadingBar.complete();
            }, 5000);
        }

        function confirmCloseFile(file, callback) {
            if (file.changed) {
                _dialog.confirm('确认信息', '文件【' + file.name + '】已修改，您确定要保存吗？', true)
                    .then(function(yes) {
                        if (yes) {
                            self.editor.save(file, callback, true);
                        } else {
                            callback();
                        }
                    });
            } else {
                callback();
            }
        }

        function closeDeletedFiles(path, equal) {
            var pathRegex = new RegExp('^' + path + '/')
            for (var i = 0; i < self.editor.files.length; i++) {
                var file = self.editor.files[i];
                if (file.opened && file.path) {
                    if (equal) {
                        if (file.path == path) {
                            self.editor.files.splice(i--, 1);
                        }
                    } else if (pathRegex.test(file.path)) {
                        self.editor.files.splice(i--, 1);
                    }
                }
            }
            if (self.editor.files.length == 0) {
                self.editor.closeAll();
            }
        }

        function parseFilePath(path) {
            var attr = {};
            if (path) {
                attr.path = path.substring(path.lastIndexOf('/') + 1);
                //
                var parent = path.substring(0, path.lastIndexOf('/'));
                var slashIndex = parent.indexOf('/');
                if (slashIndex > 0) {
                    attr.module = parent.substring(0, slashIndex);
                    parent = parent.substring(slashIndex + 1);
                    attr.path = parent + '/' + attr.path;
                } else {
                    attr.module = parent;
                }
            }
            return attr;
        }

        function getNodePath(node) {
            return _.map(node.getPath(), function(_node) {
                return _node.name;
            }).join('/');
        }
    });
});
